package com.dh.order.service.impl;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import javax.transaction.Transactional;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.dh.order.dao.OrderDetailDao;
import com.dh.order.dao.OrderMasterDao;
import com.dh.order.dto.OrderDTO;
import com.dh.order.entity.OrderDetail;
import com.dh.order.entity.OrderMaster;
import com.dh.order.enums.OrderStatusEnum;
import com.dh.order.enums.PayStatusEnum;
import com.dh.order.enums.ResultEnum;
import com.dh.order.exception.OrderException;
import com.dh.order.service.OrderService;
import com.dh.order.utils.KeyUtil;
import com.dh.product.client.Productclient;
import com.dh.product.common.DecreaseStockInput;
import com.dh.product.common.ProductInfoOutput;

/** 
* @author 作者 dinghao
* @version 创建时间：2018年11月14日 下午3:19:34 
* 类说明 
*/
@Service
public class OrderServiceImpl implements OrderService {

	@Autowired
	private OrderDetailDao orderDetailDao;
	
	@Autowired
	private OrderMasterDao orderMasterDao;
	
	@Autowired
	private Productclient productclient;
	
	@Override
	@Transactional
	public OrderDTO create(OrderDTO orderDTO) {
		String orderId = KeyUtil.genUniqueKey();
		
		
		//TODO 2.查询商品信息(调用商品服务)
		List<String> productIdList = orderDTO.getOrderDetailList().stream()
				.map(OrderDetail::getProductId)
				.collect(Collectors.toList());
		List<ProductInfoOutput> productInfoOutputsList = productclient.listForOrder(productIdList);
	    
		//TODO 3.计算总价
		BigDecimal orderAmout = new BigDecimal(BigInteger.ZERO);
		for (OrderDetail orderDetail : orderDTO.getOrderDetailList()) {
			for (ProductInfoOutput productInfoOutput : productInfoOutputsList) {
				if(productInfoOutput.getProductId().equals(orderDetail.getProductId())) {
					orderAmout = productInfoOutput.getProductPrice()
					.multiply(new BigDecimal(orderDetail.getProductQuantity()))
					.add(orderAmout);
					BeanUtils.copyProperties(productInfoOutput, orderDetail);
					orderDetail.setOrderId(orderId);
					orderDetail.setDetailId(KeyUtil.genUniqueKey());
					//订单详情入库
					orderDetailDao.save(orderDetail);
				}
			}
		}
		
		//TODO 4.扣库存(调用商品服务)
		List<DecreaseStockInput> decreaseStockInputs = orderDTO.getOrderDetailList().stream()
				.map(e->new DecreaseStockInput(e.getProductId(),e.getProductQuantity()))
				.collect(Collectors.toList());
		productclient.decreaseStock(decreaseStockInputs);
		
	    // 5.订单入库
		OrderMaster orderMaster = new OrderMaster();
		orderDTO.setOrderId(orderId);
		BeanUtils.copyProperties(orderDTO, orderMaster);
		orderMaster.setOrderAmount(orderAmout);
		orderMaster.setOrderStatus(OrderStatusEnum.NEW.getCode());
		orderMaster.setPayStatus(PayStatusEnum.WAIT.getCode());
		orderMasterDao.save(orderMaster);
		return orderDTO;
	}

	@Override
	@Transactional
	public OrderDTO finish(String orderId) {
		// 1.先查询订单
		 Optional<OrderMaster> orderMasterOptional = orderMasterDao.findById(orderId);
		if(!orderMasterOptional.isPresent()) {
			throw new OrderException(ResultEnum.ORDER_NOT_EXIST);
		}
		
		// 2.判断订单状态
		OrderMaster orderMaster = orderMasterOptional.get();
		if(OrderStatusEnum.NEW.getCode() != orderMaster.getOrderStatus()) {
			throw new OrderException(ResultEnum.ORDER_STATUS_ERROR);
		}
		
		// 3.修改订单状态为完结
		orderMaster.setOrderStatus(OrderStatusEnum.FINISHED.getCode());;
		orderMasterDao.save(orderMaster);
		
		// 4.查询订单详情
		List<OrderDetail> orderDetailList = orderDetailDao.findByOrderId(orderId);;
		if(CollectionUtils.isEmpty(orderDetailList)) {
			throw new OrderException(ResultEnum.ORDER_DETAIL_NOT_EXIST);
		} 
		OrderDTO orderDTO = new OrderDTO();
		BeanUtils.copyProperties(orderMaster, orderDTO);
		orderDTO.setOrderDetailList(orderDetailList);
		
		return orderDTO;
	}

}
